package week04.homework01MazeGame.map;

import week04.homework01MazeGame.model.Cell;
import week04.homework01MazeGame.settings.CellImage;
import week04.homework01MazeGame.settings.TerminalColor;

import java.util.Random;

/**
 * @author li
 */
public class Maze {

    private final int row;

    private final int col;

    private final Cell[][] cells;

    private static final Random RANDOM = new Random();

    public Maze(int row, int col) {
        this.row = row;
        this.col = col;
        cells = new Cell[row][col];
        do {
            generateRandomMaze();
        } while (!checkMaze());
        cells[0][0].setPlayer(true);
    }

    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }

    public Cell getCell(int x, int y) {
        return cells[x][y];
    }

    private final static int MAX_Q = 1000;

    private final static int[] MOVE = {-1, 0, 1, 0, -1};

    private boolean checkMaze() {
        int startX = 0;

        int startY = 0;

        int endX = row - 1;

        int endY = col - 1;

        if (cells[startX][startY].isObstacle() || cells[endX][endY].isObstacle()) {
            return false;
        }

        int[][] queue = new int[MAX_Q][2];

        int l = 0, r = 0;

        boolean[][] visited = new boolean[row][col];

        queue[r][0] = startX;
        queue[r++][1] = startY;
        visited[startX][startY] = true;
        while (l < r) {
            int x = queue[l][0];
            int y = queue[l++][1];

            if (x == endX && y == endY) {
                return true;
            }

            for (int i = 0, nx, ny; i < MOVE.length - 1; i++) {
                nx = x + MOVE[i];
                ny = y + MOVE[i + 1];
                if (nx >= 0 && nx < row && ny >= 0 && ny < col && !visited[nx][ny] && !cells[nx][ny].isObstacle()) {
                    queue[r][0] = nx;
                    queue[r++][1] = ny;
                    visited[nx][ny] = true;
                }
            }
        }
        return false;
    }

    private void generateRandomMaze() {
        for (int i = 0; i < cells.length; i++) {
            for (int j = 0; j < cells[i].length; j++) {
                cells[i][j] = new Cell();
                double value = RANDOM.nextDouble();
                if (value <= 0.3) {
                    cells[i][j].setObstacle(true);
                } else if (value <= 0.5) {
                    if (i != 0 || j != 0) {
                        cells[i][j].setMonster(true);
                        double itemValue = RANDOM.nextDouble();
                        if (itemValue <= 0.2) {
                            cells[i][j].setEquipment(true);
                        } else if (itemValue <= 0.7) {
                            cells[i][j].setPotion(true);
                        }
                    }
                } else if (value <= 0.7) {
                    cells[i][j].setPotion(true);
                }
            }
        }
    }

    public void display() {
        for (Cell[] cell : cells) {
            for (Cell value : cell) {
                CellImage image = value.getCellImage();
                String getImage = image.getImage();
                if (image == CellImage.PASSAGE && value.isPlayerPassed()) {
                    getImage = TerminalColor.colorize(getImage, TerminalColor.GREEN);
                }
                System.out.print(getImage);
            }
            System.out.println();
        }
    }

}
